package thread

import (
	"strings"
	"testing"

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/suite"
	"notabug.org/ropemann/imabon/src/common"
)

type ThreadTestSuite struct {
	suite.Suite
	title       string
	author      string
	body        string
	image       string
	threadId    string
	board       string
	newThreadId string
}

func (s *ThreadTestSuite) SetupSuite() {
	common.LoadConfig("../../../.env")

	s.title = "test_title"
	s.author = "test_author"
	s.body = "test_body"
	s.image = "test_image"
	s.threadId = "625b8273c84324aea98ce004"
	s.board = "ani"
}

func (s *ThreadTestSuite) TestNewThread() {
	thread := NewThread(s.title, s.author, s.body, s.image)
	assert.Equal(s.T(), s.title, thread.Title)
	assert.Equal(s.T(), s.author, thread.AuthorName)
	assert.Equal(s.T(), s.body, thread.Body)
	assert.Equal(s.T(), s.image, thread.Image)
	assert.NotNil(s.T(), thread.ID)
}

func (s *ThreadTestSuite) TestGetAllThreadsByBoard() {
	threads := GetAllThreadsByBoard(s.board)
	assert.NotEmpty(s.T(), threads)
}

func (s *ThreadTestSuite) TestGetAllThreadsByBoardInvalid() {
	threads := GetAllThreadsByBoard("invalid_board")
	assert.Empty(s.T(), threads)
}

func (s *ThreadTestSuite) TestCreateThread() {
	thread := NewThread(s.title, s.author, s.body, s.image)
	threadId, err := CreateThread(s.board, *thread)
	s.newThreadId = threadId
	assert.Nil(s.T(), err)
	assert.NotNil(s.T(), threadId)
}

func (s *ThreadTestSuite) TestGetThreadById() {
	thread := GetThreadById(s.board, s.newThreadId)
	b, _ := thread.ID.MarshalJSON()
	returnedId := strings.ReplaceAll(string(b), "\"", "")
	assert.Equal(s.T(), s.newThreadId, returnedId)
}

func (s *ThreadTestSuite) TestGetThreadByIdInvalid() {
	thread := GetThreadById(s.board, "invalid")
	assert.Empty(s.T(), thread)
}

func (s *ThreadTestSuite) TestGetMostRecentThreads() {
	recent := GetMostRecentThreads()
	assert.NotEmpty(s.T(), recent)
}

func (s *ThreadTestSuite) TestGetMostRecentPost() {
	thread := GetThreadById(s.board, s.threadId)
	post := thread.GetMostRecentPost()
	assert.NotEmpty(s.T(), post)
}

func (s *ThreadTestSuite) TestGetMostRecentPostEmpty() {
	thread := GetThreadById(s.board, s.newThreadId)
	post := thread.GetMostRecentPost()
	assert.Empty(s.T(), post)
}

func (s *ThreadTestSuite) TestZZDeleteThread() {
	res, err := DeleteThread(s.board, s.newThreadId)
	assert.Nil(s.T(), err)
	assert.Greater(s.T(), int(res), 0)
}

func (s *ThreadTestSuite) TestZZDeleteThreadNotFound() {
	res, err := DeleteThread(s.board, "invalid")
	assert.Nil(s.T(), err, res)
	assert.Equal(s.T(), int(res), 0)
}

func TestThreadTestSuite(t *testing.T) {
	suite.Run(t, new(ThreadTestSuite))
}
